package sis.myjunit;/*
 * @auther 顶风少年
 * @mail dfsn19970313@foxmail.com
 * @date 2019-08-03 17:22
 * @notify
 * @version 1.0
 */

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class TestRunner {
    //调用方提供
    private Class testClass;
    //失败次数
    private int failed = 0;
    //Class中的方法列表
    private Set<Method> testMethods = null;

    //被忽略的测试方法列表
    private Map<Method,Ignore> ignoredMethods = null;

    //构造函数接收一个 Class
    public TestRunner(Class testClass) {
        this.testClass = testClass;
    }

    //接收一个 class路径 并创建Class
    public TestRunner(String className) throws Exception {
        this(Class.forName(className));
    }

    //返回Class 中的 方法列表
    public Set<Method> getTestMethods() {
        //如果方法列表为null
        if (testMethods == null) {
            //加载方法列表
            loadTestMethods();
        }
        //返回Class 中的 方法列表
        return testMethods;
    }
    //加载方法列表
    private void loadTestMethods() {
        //实例化测试方法集合
        testMethods = new HashSet<>();
        //实例化忽略方法集合
        ignoredMethods = new HashMap<>();
        //获取 Class中的方法 数组
        for (Method method : testClass.getDeclaredMethods()) {
            //判断是否使用了test注解
            if(method.isAnnotationPresent(Test.class)){
                //判断是否使用了ignore注解
                if(method.isAnnotationPresent(Ignore.class)){
                    Ignore ignore = method.getAnnotation(Ignore.class);
                    ignoredMethods.put(method,ignore);
                }else{
                    //遍历添加方法.
                    testMethods.add(method);
                }
            }
        }
    }

    //循环运行每个方法
    public void run() {
        for (Method method : getTestMethods()) {
            run(method);
        }
    }

    //运行方法
    private void run(Method method) {
        try {
            //反射创建 对象实例
            Object testObject = testClass.newInstance();
            //执行方法
            method.invoke(testObject, new Object[]{});
        } catch (Exception e) {
            //打印错误
            Throwable cause = e.getCause();
            if (cause instanceof AssertionError) {
                System.out.println(cause.getMessage());
            } else {
                e.printStackTrace();
            }
            //记录错误次数
            failed++;
        }
    }

    //成功次数
    public int passed() {
        return testMethods.size() - failed;
    }

    //失败次数
    public int failed() {
        return failed;
    }

    //获取忽略列表
    public Map<Method,Ignore> getIgnoredMethods(){
        return ignoredMethods;
    }

}
